package framework.entities;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.testng.SkipException;
import framework.BaseEntity;


/** Класс для сериализации/десериализации в файл объектов
 */
public class SerializeEntity extends BaseEntity{

	private static final String PLAN_ZAK_PREFIX = "planZakupki";
	private static final String POLOZH_ZAK_PREFIX = "polozhZak";
	private static final String PLAN_ZAK_PROEKT_IZM_PREFIX = "planZakProektIzm";
	private static final String POLOZH_ZAK_PROEKT_IZM_PREFIX = "polozhZakProektIzm";
	private static final String ORG_MAIN_PREFIX = "organizationMain";
	private static final String ORG_SLAVE_PREFIX = "organizationSlave";
	private static final String SVYAZ_1_PREFIX = "svyaz_1";
	private static final String SVYAZ_2_PREFIX = "svyaz_2";
	private static final String ZAKUPKA_OK_PREFIX = "zakupkaOK";
	private static final String ZAKUPKA_PROEKT_IZM_OK_PREFIX = "zakupkaProektIzmOk";
	private static final String PLAN_ZAK_IMPORT_PREFIX = "planZakImport";
	private static final String ZAKUPKA_IMPORT_PREFIX = "zakImport";
	private static final String POLOZHENIE_ZAKUPKI_IMPORT_PREFIX = "polozhZakImport";
	private static final String PURCHASE_NOTICE_OK_IMPORT_PREFIX = "purchaseNoticeOKImport";
	private static final String PURCHASE_NOTICE_OA_IMPORT_PREFIX = "purchaseNoticeOAImport";
	private static final String PURCHASE_NOTICE_AE_IMPORT_PREFIX = "purchaseNoticeAEImport";
	private static final String PURCHASE_NOTICE_ZK_IMPORT_PREFIX = "purchaseNoticeZKImport";
	private static final String PURCHASE_NOTICE_INOI_IMPORT_PREFIX = "purchaseNoticeInoiImport";
	private static final String PROTOCOL_VSCRYTIYA_CONVERTOV_PREFIX = "protocolVskConvertov";
	private static final String PROTOCOL_VSCRYTIYA_CONVERTOV_PROJECT_IZM_PREFIX = "protocolVskConvertovIzm";
	private static final String PROTOCOL_RASSM_ZAYAVOK_PREFIX = "protocolRassmZayavok";
	private static final String PROTOCOL_RASSM_ZAYAVOK_PROJECT_IZM_PREFIX = "protocolRassmZayavokIzm";
	private static final String PROTOCOL_OCENKI_PREFIX = "protocolOcenki";
	private static final String PROTOCOL_OCENKI_PROJECT_IZM_PREFIX = "protocolOcenkiIzm";
	private static final String SVEDENIYA_O_DOGOVORE_PREFIX="svedeniyaODogovore";
	private static final String SVEDENIYA_O_DOGOVORE_IZM_PREFIX="svedeniyaODogovoreIzm";
	private static final String PROTOCOL_INOGO_SPOSOBA_PREFIX = "protocolInoySposob";
	private static final String PROTOCOL_INOGO_SPOSOBA_IZM_PREFIX = "protocolInoySposobIzm";
	private static final String OTCHETNOST_O_DOGOVORE_PREFIX = "otchetnostODogovorah";
	private static final String UTOCHNENNYE_TREBOVANIYA_PREFIX = "utochTreb";
	private static final String UTOCHNENNYE_TREBOVANIYA_IZM_PREFIX = "utochTrebIzm";
	private static final String OTKAZ_PREFIX = "otkaz";
	private static final String ZHALOBA_PREFIX = "zhaloba";

	/** Перечисление доступных для сериализации сущностей
	 */
	public static enum Entities{
		PLAN_ZAKUPKI("План закупки"), POLOZHENIE_ZAKUPKI("Положение закупки"), PLAN_ZAKUPKI_PROEKT_IZMENENIY("План закупки - проект изменений"),
		POLOZHENIE_ZAKUPKI_PROEKT_IZMENENIY("Положение закупки - проект изменений"), ORGANIZATION_MAIN("Главная организация"),
		ORGANIZATION_SLAVE("Второстепенная организация"), SVYAZ_1("Связь между организациями"), SVYAZ_2("Связь между организациями"),
		ZAKUPKA_OK("Закукпка (Открытый конкурс)"), ZAKUPKA_PROEKT_IZM_OK("Проект изменения извещения о закупке(ОК)"),
		PLAN_ZAKUPKI_IMPORT("План закупки (Импорт)"), ZAKUPKA_IMPORT("Закупка (Импорт)"),
		POLOZHENIE_ZAKUPKI_IMPORT("Положение закупки (Импорт)"),
		PURCHASE_NOTICE_OK_IMPORT("Закупка Открытый конкурс импорт"),PURCHASE_NOTICE_OA_IMPORT("Закупка Открытый аукцион импорт"),
		PURCHASE_NOTICE_AE_IMPORT("Открытый аукцион в электронной форме Импорт"),
		PURCHASE_NOTICE_ZK_IMPORT("Закупка запроса котировок"),PURCHASE_NOTICE_INOI_IMPORT("Закупка иным способом"),
		PROTOCOL_VSKRYTIYA_CONVERTOV("Протокол вскрытия конвертов"), PROTOCOL_VK_IZM("Протокол вскрытия конвертов(Проект изменений)"),
		PROTOCOL_RASSM_ZAYAVOK("Протокол рассмотрения заявок"), PROTOCOL_RZ_IZM("Протокол рассмотрения заявок (Проект изменений)"),
		PROTOCOL_OCENKI("Протокол оценки и сопастовления результатов"), PROTOCOL_OCENKI_IMZ("Протокол оценки и сопоставления результатов (Проект изменений)"),
		SVEDENIYA_O_DOGOVORE("Сведения о договоре"), SVEDENIYA_O_DOGOVORE_IZM("Сведения о договоре (Проект изменений)"),
		PROTOCOL_INOGO_SPOSOBA("Протокол иного способа"), PROTOCOL_INOGO_SPOSOBA_IZM("Протокол иного способа (Проект изменений)"),OTCHETNOST_O_DOGOVORE("Отчетность по договорам"),
		UTOCHNENNYE_TREBOVANIYA("Уточненные требования"), UTOCHNENNYE_TREBOVANIYA_IZM("Уточненные требования (Проект изменений)"), OTKAZ("Отказ"),
		ZHALOBA("Жалоба"), NP("Недобросовестный поставщик");

		private String	val;

		/** Присваивает название элементу перечисления
		 * @param name название
		 */
		Entities(String name) {
			val = name;
		}

		@Override
		public String toString() {
			return val;
		}
	}

	/** Сериализация основных сущностей
	 * @param obj сериализуемый объект
	 * @param entity тип объекта
	 */
	public static void serializeEntity(Entities entity, Object obj){
		String prefix = "";

		if (obj instanceof Organizaciya && entity.equals(Entities.ORGANIZATION_MAIN)){
			prefix = ORG_MAIN_PREFIX;
		}
		/*else if (obj instanceof PlanZakupki && entity.equals(Entities.PLAN_ZAKUPKI_PROEKT_IZMENENIY)){
			prefix = PLAN_ZAK_PROEKT_IZM_PREFIX;
		}else if(obj instanceof PlanZakupki && entity.equals(Entities.PLAN_ZAKUPKI)){
			prefix = PLAN_ZAK_PREFIX;
		}else if(obj instanceof PolozhenieZakupki && entity.equals(Entities.POLOZHENIE_ZAKUPKI)){
			prefix = POLOZH_ZAK_PREFIX;
		}else if(obj instanceof PolozhenieZakupki && entity.equals(Entities.POLOZHENIE_ZAKUPKI_PROEKT_IZMENENIY)){
			prefix = POLOZH_ZAK_PROEKT_IZM_PREFIX;
		}
		}else if(obj instanceof Organizaciya && entity.equals(Entities.ORGANIZATION_SLAVE)){
			prefix = ORG_SLAVE_PREFIX;
		}else if(obj instanceof SvyazOrg && entity.equals(Entities.SVYAZ_1)){
			prefix = SVYAZ_1_PREFIX;
		}else if(obj instanceof SvyazOrg && entity.equals(Entities.SVYAZ_2)){
			prefix = SVYAZ_2_PREFIX;
		}else if(obj instanceof Zakupka && entity.equals(Entities.ZAKUPKA_OK)){
			prefix = ZAKUPKA_OK_PREFIX;
		}else if(obj instanceof Zakupka && entity.equals(Entities.ZAKUPKA_PROEKT_IZM_OK)){
			prefix = ZAKUPKA_PROEKT_IZM_OK_PREFIX;
		}else if(obj instanceof PlanZakupki && entity.equals(Entities.PLAN_ZAKUPKI_IMPORT)){
			prefix = PLAN_ZAK_IMPORT_PREFIX;
		}else if(obj instanceof Zakupka && entity.equals(Entities.ZAKUPKA_IMPORT)){
			prefix = ZAKUPKA_IMPORT_PREFIX;
		}else if(obj instanceof PolozhenieZakupki && entity.equals(Entities.POLOZHENIE_ZAKUPKI_IMPORT)){
			prefix = POLOZHENIE_ZAKUPKI_IMPORT_PREFIX;
		}else if(obj instanceof PurchaseNotice && entity.equals(Entities.PURCHASE_NOTICE_OK_IMPORT)){
			prefix = PURCHASE_NOTICE_OK_IMPORT_PREFIX;
		}else if(obj instanceof PurchaseNotice && entity.equals(Entities.PURCHASE_NOTICE_OA_IMPORT)){
			prefix = PURCHASE_NOTICE_OA_IMPORT_PREFIX;
		}else if(obj instanceof PurchaseNotice && entity.equals(Entities.PURCHASE_NOTICE_AE_IMPORT)){
			prefix = PURCHASE_NOTICE_AE_IMPORT_PREFIX;
		}else if(obj instanceof PurchaseNotice && entity.equals(Entities.PURCHASE_NOTICE_ZK_IMPORT)){
			prefix = PURCHASE_NOTICE_ZK_IMPORT_PREFIX;
		}else if(obj instanceof PurchaseNotice && entity.equals(Entities.PURCHASE_NOTICE_INOI_IMPORT)){
			prefix = PURCHASE_NOTICE_INOI_IMPORT_PREFIX;
		}else if(obj instanceof ProtocolVskrytiyaConvertov && entity.equals(Entities.PROTOCOL_VSKRYTIYA_CONVERTOV)){
			prefix = PROTOCOL_VSCRYTIYA_CONVERTOV_PREFIX;
		}else if(obj instanceof ProtocolRassmZayavok && entity.equals(Entities.PROTOCOL_RASSM_ZAYAVOK)){
			prefix = PROTOCOL_RASSM_ZAYAVOK_PREFIX;
		}else if(obj instanceof ProtocolOcenki && entity.equals(Entities.PROTOCOL_OCENKI)){
			prefix = PROTOCOL_OCENKI_PREFIX;
		}else if(obj instanceof ProtocolVskrytiyaConvertov && entity.equals(Entities.PROTOCOL_VK_IZM)){
			prefix = PROTOCOL_VSCRYTIYA_CONVERTOV_PROJECT_IZM_PREFIX;
		}else if(obj instanceof ProtocolRassmZayavok && entity.equals(Entities.PROTOCOL_RZ_IZM)){
			prefix = PROTOCOL_RASSM_ZAYAVOK_PROJECT_IZM_PREFIX;
		}else if(obj instanceof ProtocolOcenki && entity.equals(Entities.PROTOCOL_OCENKI_IMZ)){
			prefix = PROTOCOL_OCENKI_PROJECT_IZM_PREFIX;
		}else if(obj instanceof SvedeniyaODogovore && entity.equals(Entities.SVEDENIYA_O_DOGOVORE)){
			prefix = SVEDENIYA_O_DOGOVORE_PREFIX;
		}else if(obj instanceof SvedeniyaODogovore && entity.equals(Entities.SVEDENIYA_O_DOGOVORE_IZM)){
			prefix = SVEDENIYA_O_DOGOVORE_IZM_PREFIX;
		}else if(obj instanceof ProtocolInoySposob && entity.equals(Entities.PROTOCOL_INOGO_SPOSOBA)){
			prefix = PROTOCOL_INOGO_SPOSOBA_PREFIX;
		}else if(obj instanceof ProtocolInoySposob && entity.equals(Entities.PROTOCOL_INOGO_SPOSOBA_IZM)){
			prefix = PROTOCOL_INOGO_SPOSOBA_IZM_PREFIX;
		}else if(obj instanceof OtchetnostODogovore && entity.equals(Entities.OTCHETNOST_O_DOGOVORE)){
			prefix = OTCHETNOST_O_DOGOVORE_PREFIX;
		}else if(obj instanceof UtochnennyeTrebovaniya && entity.equals(Entities.UTOCHNENNYE_TREBOVANIYA)){
			prefix = UTOCHNENNYE_TREBOVANIYA_PREFIX;
		}else if(obj instanceof UtochnennyeTrebovaniya && entity.equals(Entities.UTOCHNENNYE_TREBOVANIYA_IZM)){
			prefix = UTOCHNENNYE_TREBOVANIYA_IZM_PREFIX;
		}else if(obj instanceof Otkaz && entity.equals(Entities.OTKAZ)){
			prefix = OTKAZ_PREFIX;
		}else if(obj instanceof Zhaloba && entity.equals(Entities.ZHALOBA)){
			prefix = ZHALOBA_PREFIX;
		}*/

		try{
			FileOutputStream fileOut = new FileOutputStream(prefix + ".ser");
			ObjectOutputStream out = new ObjectOutputStream(fileOut);
			out.writeObject(obj);
			out.close();
			fileOut.close();
		}catch(IOException i){
			logger.info("Возникла ошибка при сериализации объекта " + i.getStackTrace());
		}
	}

	/** Десериализирует объект из файла
	 * @param entity тип объекта
	 * @return объект
	 */
	public static Object deserializeEntity(Entities entity){
		String prefix = "";
		switch(entity){
			case PLAN_ZAKUPKI:
				prefix = PLAN_ZAK_PREFIX;
				break;
			case POLOZHENIE_ZAKUPKI:
				prefix = POLOZH_ZAK_PREFIX;
				break;
			case PLAN_ZAKUPKI_PROEKT_IZMENENIY:
				prefix = PLAN_ZAK_PROEKT_IZM_PREFIX;
				break;
			case POLOZHENIE_ZAKUPKI_PROEKT_IZMENENIY:
				prefix = POLOZH_ZAK_PROEKT_IZM_PREFIX;
				break;
			case ORGANIZATION_MAIN:
				prefix = ORG_MAIN_PREFIX;
				break;
			case ORGANIZATION_SLAVE:
				prefix = ORG_SLAVE_PREFIX;
				break;
			case SVYAZ_1:
				prefix = SVYAZ_1_PREFIX;
				break;
			case SVYAZ_2:
				prefix = SVYAZ_2_PREFIX;
				break;
			case ZAKUPKA_OK:
				prefix = ZAKUPKA_OK_PREFIX;
				break;
			case ZAKUPKA_PROEKT_IZM_OK:
				prefix = ZAKUPKA_PROEKT_IZM_OK_PREFIX;
				break;
			case PLAN_ZAKUPKI_IMPORT:
				prefix = PLAN_ZAK_IMPORT_PREFIX;
				break;
			case ZAKUPKA_IMPORT:
				prefix = ZAKUPKA_IMPORT_PREFIX;
				break;
			case POLOZHENIE_ZAKUPKI_IMPORT:
				prefix = POLOZHENIE_ZAKUPKI_IMPORT_PREFIX;
				break;
			case PURCHASE_NOTICE_OK_IMPORT:
				prefix = PURCHASE_NOTICE_OK_IMPORT_PREFIX;
				break;
			case PURCHASE_NOTICE_OA_IMPORT:
				prefix = PURCHASE_NOTICE_OA_IMPORT_PREFIX;
				break;
			case PURCHASE_NOTICE_AE_IMPORT:
				prefix = PURCHASE_NOTICE_AE_IMPORT_PREFIX;
				break;
			case PURCHASE_NOTICE_ZK_IMPORT:
				prefix = PURCHASE_NOTICE_ZK_IMPORT_PREFIX;
				break;
			case PURCHASE_NOTICE_INOI_IMPORT:
				prefix = PURCHASE_NOTICE_INOI_IMPORT_PREFIX;
				break;
			case PROTOCOL_VSKRYTIYA_CONVERTOV:
				prefix = PROTOCOL_VSCRYTIYA_CONVERTOV_PREFIX;
				break;
			case PROTOCOL_RASSM_ZAYAVOK:
				prefix = PROTOCOL_RASSM_ZAYAVOK_PREFIX;
				break;
			case PROTOCOL_OCENKI:
				prefix = PROTOCOL_OCENKI_PREFIX;
				break;
			case PROTOCOL_VK_IZM:
				prefix = PROTOCOL_VSCRYTIYA_CONVERTOV_PROJECT_IZM_PREFIX;
				break;
			case PROTOCOL_RZ_IZM:
				prefix = PROTOCOL_RASSM_ZAYAVOK_PROJECT_IZM_PREFIX;
				break;
			case PROTOCOL_OCENKI_IMZ:
				prefix = PROTOCOL_OCENKI_PROJECT_IZM_PREFIX;
				break;
			case SVEDENIYA_O_DOGOVORE:
				prefix = SVEDENIYA_O_DOGOVORE_PREFIX;
				break;
			case SVEDENIYA_O_DOGOVORE_IZM:
				prefix = SVEDENIYA_O_DOGOVORE_IZM_PREFIX;
				break;
			case PROTOCOL_INOGO_SPOSOBA:
				prefix = PROTOCOL_INOGO_SPOSOBA_PREFIX;
				break;
			case PROTOCOL_INOGO_SPOSOBA_IZM:
				prefix = PROTOCOL_INOGO_SPOSOBA_IZM_PREFIX;
				break;
			case OTCHETNOST_O_DOGOVORE:
				prefix = OTCHETNOST_O_DOGOVORE_PREFIX;
				break;
			case UTOCHNENNYE_TREBOVANIYA:
				prefix = UTOCHNENNYE_TREBOVANIYA_PREFIX;
				break;
			case UTOCHNENNYE_TREBOVANIYA_IZM:
				prefix = UTOCHNENNYE_TREBOVANIYA_IZM_PREFIX;
				break;
			case OTKAZ:
				prefix = OTKAZ_PREFIX;
				break;
			case ZHALOBA:
				prefix = ZHALOBA_PREFIX;
				break;
			default:
				break;
		}

		 try{
			String path = prefix + ".ser";
			// Чтобы иметь возможность запускать на jenkins используя файлы из папки debugfiles
			if(!(System.getProperty("useDebugFiles") == null) && (System.getProperty("useDebugFiles").equals("true"))){
				logger.warn("Файлы сериализации берутся из директории \"debugfiles\"");
				File f = new File("./src/test/resources/debugfiles/" + prefix + ".ser");
				if(!f.exists()){
					f = new File("../src/test/resources/debugfiles/" + prefix + ".ser");
				}
				path = f.getAbsolutePath();
			}else{
				path = prefix + ".ser";
				File file = new File(path);
					if(!file.exists()){
						path = "../" + prefix + ".ser";
						file = new File(path);
					}
					path = file.getAbsolutePath();
			}
			FileInputStream fileIn = new FileInputStream(path);
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Object obj = in.readObject();
            in.close();
            fileIn.close();
            return obj;
        }catch(IOException i){
            logger.info("Не удалось десериализировать файл " + i.toString());
        	return null;
        }catch(ClassNotFoundException c){
        	logger.info("Не найден нужный класс в указанном файле " + c.toString());
        	return null;
        }
	}

	/** Получает сущность из файла
	 * @param entity тип сущности
	 * @return сущность
	 */
	public static Object getEntity(Entities entity){
		Object obj = deserializeEntity(entity); //
			if(obj == null) {
				/*try {
					new File("stop").createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
				}*/
				throw new SkipException(entity.toString() + " не был создан в предыдущих тестах.");
			}
		return obj;
	}


	@Override
	protected String formatLogMsg(String message) {
		return null;
	}
}
